package com.system.vote.admin.security;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.system.vote.common.utils.IpUtils;
import com.system.vote.core.http.Result;
import com.system.vote.admin.entity.SysAccount;
import com.system.vote.admin.entity.SysLoginLog;
import com.system.vote.admin.entity.SysMenu;
import com.system.vote.admin.entity.SysRole;
import com.system.vote.admin.service.SysAccountService;
import com.system.vote.admin.service.SysLoginLogService;
import com.system.vote.admin.service.SysMenuService;
import com.system.vote.admin.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


@Component
@Slf4j
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    private SysAccountService accountService;
    @Autowired
    private SysRoleService roleService;
    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysLoginLogService sysLoginLogService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();

        String username = authentication.getName();
        SysAccount currentUser = accountService.getByUserName(username);
        String token = JwtUtil.getJWTToken(String.valueOf(currentUser.getId()), username);

        List<SysRole> roleList = roleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id=" + currentUser.getId()));
        //遍历所有的角色，获取所有菜单权限而且不重复
        Set<SysMenu> menuCodeSet = new HashSet<>();
        for (SysRole sysRole : roleList) {
            List<SysMenu> menuList = sysMenuService.list(new QueryWrapper<SysMenu>().inSql("id", "select menu_id from sys_role_menu where role_id=" + sysRole.getId()));
            menuCodeSet.addAll(menuList);
        }

        currentUser.setRoles(roleList.stream().map(SysRole::getName).collect(Collectors.joining(",")));
        List<SysMenu> sysMenuList = new ArrayList<>(menuCodeSet);
        //排序
        sysMenuList.sort(Comparator.comparing(SysMenu::getOrderNum));
        //转菜单树
        List<SysMenu> menuList = sysMenuService.buildTreeMenu(sysMenuList, false);

        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("currentUser", currentUser);
        result.put("menuList", menuList);
        result.put("authorityStr", accountService.getUserAuthorityInfo(currentUser.getId()));

        //登录日志
        String ip = IpUtils.getIpAddr(request);
        String cityInfo = null;
        try {
            cityInfo = IpUtils.getCityInfo(ip);
        } catch (Exception e) {
            log.error("获取ip归属地信息失败！");
        }

        SysLoginLog sysLoginLog = new SysLoginLog();
        String userAgentStr = request.getHeader("User-Agent");
        sysLoginLog.setUserAgent(userAgentStr);
        UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
        sysLoginLog.setDeviceName(userAgent.getOs().getName());
        sysLoginLog.setType(1);
        sysLoginLog.setBrowserName(userAgent.getBrowser().getName());
        sysLoginLog.setName(currentUser.getUsername());
        sysLoginLog.setIp(ip);
        sysLoginLog.setUid(currentUser.getId());
        sysLoginLog.setIpAttribution(cityInfo);
        sysLoginLog.setCreateTime(new Date());
        sysLoginLogService.save(sysLoginLog);
        outputStream.write(JSONUtil.toJsonStr(Result.success("登录成功", result)).getBytes());
        outputStream.flush();
        outputStream.close();
    }
}
